# coding=utf-8

from persistents import dblayer
from utils.SingletonPattern import singleton
from multiprocessing import Process
from managers.globalarea import app_config
from components.logger import logger
from components.objs import Task_In_Redis


@singleton
class RedisServices(object):

    def __init__(self):
        self.redis_db = dblayer.DBLayer().get_redis_handler()

    def exist(self, name):
        return self.redis_db.exists(name)

    def delete(self, name):
        return self.redis_db.delete(name)

    def keys(self, pattern='*'):
        return self.redis_db.keys(pattern)

    def hmset(self, name, field_dict):
        self.redis_db.hmset(name, field_dict)

    def hmget(self, name, key, *args):
        return self.redis_db.hmget(name, key, *args)

    def hgetall(self, name):
        return self.redis_db.hgetall(name)

    def hset(self, key, field, value):
        self.redis_db.hset(key, field, value)

    def hget(self, key, field):
        return self.redis_db.hget(key, field)

    def hkeys(self, key):
        return self.redis_db.hkeys(key)

    def monkey_task_insert(self, task_name, list_param):
        if len(list_param) == len(Task_In_Redis.data_structure_of_monkey_task):
            task_info = dict(zip(Task_In_Redis.data_structure_of_monkey_task, list_param))
            self.hmset(task_name, task_info)
        else:
            pass
            # logger.info("parameters are shoter!")

    # def device_info_insert(self, device_name, list_param):
    #     if len(list_param) == len(dict_of_data_structure[structure_name[1]]):
    #         task_info = dict(zip(dict_of_data_structure[structure_name[1]], list_param))
    #         self.hmset(device_name, task_info)
    #     else:
    #         pass

    def setex(self, name, ex, value=0):
        self.redis_db.setex(name, ex, value)

    def set(self, name, value):
        self.redis_db.set(name, value)

    def get(self, name):
        return self.redis_db.get(name)

    def timing_task(self, func_kw_mapping, *args, **kwargs):
        """
        定时任务处理
        :param func_kw_mapping: {keyword：func,...}类型数据
        :param args: 暂未使用
        :param kwargs: 暂未使用
        :return: 定时任务处理器的pid
        """
        p = self.redis_db.pubsub()
        p.psubscribe('__keyevent@0__:expired')

        def task_listening():
            process_list = {}
            for expired_info in p.listen():
                logger.info('expired_info: %s' % (str(expired_info),))
                if 'pmessage' == expired_info['type']:
                    key = expired_info['data'].split(app_config.spec)[0]
                    if key in func_kw_mapping.keys():
                        p_key = app_config.task_tag + app_config.spec + expired_info['data']
                        task = lambda x=p_key: func_kw_mapping[key]()(x)
                        process_task = Process(target=task, name='task-process' + func_kw_mapping[key].__name__)
                        process_task.start()
                        process_list[process_task.pid] = process_task
                    elif key == "pk":
                        info = expired_info['data'].split(app_config.spec)[1:]
                        p_id, tagdate = info
                        logger.info(process_list)
                        logger.info(p_id)
                        logger.info(tagdate)
                        for pd in process_list.keys():
                            logger.info(type(pd))
                            if process_list[pd].is_alive() and str(pd) == p_id:
                                process_list[pd].terminate()
                                process_list[pd].join()
                                del process_list[pd]
                            else:
                                del process_list[pd]
                        terminate = lambda x=info: func_kw_mapping['terminate']()(x)
                        Process(target=terminate, name='terminate-process' + p_id).start()
                    else:
                        logger.info("失效键无对应操作！ (key: %s)" % (key,))
                        pass

        process_task = Process(target=task_listening, name='task-process')
        process_task.start()
        return process_task.pid


# 构建Process入参，[sn，省略的打包机型， 打包版本， 包适配的区域， 是否需要打包， 是否执行monkey测试， 当前的连接到电脑的设备信息（占时未使用到）， 拼接的monkey测试指令， monkey测试的次数]
# ['2644fefa', 'polaris', u'o-dev', u'cn', 1, 1, u"'monkey -p com.android.settings -v -v -v -s 1000 --ignore-crashes --ignore-timeouts --ignore-security-exceptions --kill-process-after-error --monitor-native-crashes  --pct-touch 30 --pct-motion 20 --pct-trackball 0 --pct-nav 20 --pct-majornav 15 --pct-syskeys 0 --pct-appswitch 5 --pct-anyevent 10 --throttle 500 100000 > /sdcard/monkey.log'", '0']

structure_name = ['monkey_test', 'device_info']

# data_structure_of_monkey_task = ['sn', 'product_name', 'version', 'area', 'build_if', 'monkey_test_if', 'monkey_cmd',
#                                  'times', 'execpolicy', 'weekdays', 'iter_time', 'long_time', 'point_time']

data_structure_of_devices = ['product_name', 'versions', 'areas']

# dict_of_data_structure = {structure_name[0]: data_structure_of_monkey_task,
#                           structure_name[1]: data_structure_of_devices}

if __name__ == '__main__':
    r = RedisServices()
    print r.keys('task_monkey_*')
    # r.hmset('xx', {'a2': '1', 'a3': '1'})
    # print r.redis_db.hgetall('xx')
    # print r.hmget('xx', 'a2', 'a3', 'a4')
    # t_m = ['2644fefa', 'polaris', u'o-dev', u'cn', 1, 1,
    #        u"'monkey -p com.android.settings -v -v -v -s 1000 --ignore-crashes --ignore-timeouts --ignore-security-exceptions --kill-process-after-error --monitor-native-crashes  --pct-touch 30 --pct-motion 20 --pct-trackball 0 --pct-nav 20 --pct-majornav 15 --pct-syskeys 0 --pct-appswitch 5 --pct-anyevent 10 --throttle 500 100000 > /sdcard/monkey.log'",
    #        '0']
    # # map_t = zip(dict_of_data_structure["monkey_test"], t_m)
    # # print map_t
    # # print dict(map_t)
    # if r.exist('task_test'):
    #     r.delete('task_test')
    # import datetime
    #
    # timing = str(datetime.datetime.now())
    # r.monkey_task_insert('task_monkey_' + timing, t_m)
    # r.setex('monkey_1' + str(datetime.datetime.now()), 6)
    # r.setex('monkey_2' + str(datetime.datetime.now()), 8)
    # r.setex('monkey_3' + str(datetime.datetime.now()), 10)
    # r.setex('monkey_4' + str(datetime.datetime.now()), 12)
    # print r.hmget('task_monkey_' + timing, 'sn', 'product_name', 'version', 'area', 'build_if', 'monkey_test_if',
    #               'monkey_cmd',
    #               'times')
    #
    #
    # def do(args):
    #     print args
    #
    #
    # map_f = {'monkey': do}
    # r.timing_task(map_f)
    # import time
    #
    # try:
    #     while True:
    #         time.sleep(1)
    # except (KeyboardInterrupt, SystemExit):
    pass
